﻿using System.IO;
using UnityEditor;
using UnityEngine;
using Extensions;

namespace TC
{
    public class BluePrintEditor : EditorWindow
    {
        public static FlowGraph graph;
        public static FlowGraphSurface flowGraphSurface;
        private static BluePrintEditor win;
        private static NodeInfoInspector nodeInfoEditor;
        private static ContextEditor contextWin;
        private int titleHeight = 20;
        private string resPath = "Assets";
        private GraphSource res;

        [MenuItem("Window/BluePrint")]
        public static void OpenWindow()
        {
            win = EditorWindow.GetWindow<BluePrintEditor>();
            win.titleContent = new GUIContent("BluePrint");
            win.Show(true);
            nodeInfoEditor = EditorWindow.GetWindow<NodeInfoInspector>("Node Info");
            nodeInfoEditor.Show(true);
            contextWin = EditorWindow.GetWindow<ContextEditor>("Context");
            contextWin.ShowTab();
            win.DockWindow(nodeInfoEditor, ExtensionMethods.DockPosition.Left);
            win.DockWindow(contextWin, ExtensionMethods.DockPosition.Bottom);
        }

        private bool willRepaint { get =>
                (((flowGraphSurface != null) ? flowGraphSurface.willRepaint : false) 
                || ((nodeInfoEditor != null) ? nodeInfoEditor.invokeParentRepaint : false)
                || ((contextWin != null) ? contextWin.invokeParentRepaint : false)); set { } }

        private void OnEnable()
        {
            wantsMouseMove = true;
            wantsMouseEnterLeaveWindow = true;
            willRepaint = true;
            if (graph == null)
            {
                graph = new FlowGraph(new Context(), new Flow());
                flowGraphSurface = new FlowGraphSurface(graph);
            }  
        }

        private void Awake()
        {
            graph = new FlowGraph(new Context(), new Flow());
            flowGraphSurface = new FlowGraphSurface(graph);
        }

        private void OnDestroy()
        {
            graph = null;
            flowGraphSurface = null;
        }


        public void OnGUI()
        {
            //draw title
            OnTitleGUI();

            //draw graph
            flowGraphSurface.OnDraw(new Rect(0, titleHeight, position.width, position.height));

            //event
            flowGraphSurface.OnEvent();
        }

        private void OnTitleGUI()
        {
            GUILayout.BeginArea(new Rect(0, 0, position.width, titleHeight));
            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Width(position.width));
            if (GUILayout.Button("Save", EditorStyles.toolbarButton, GUILayout.Width(60)))
            {
                string path = EditorUtility.SaveFilePanelInProject("Save", "test", "json", "message", resPath);

                if (string.IsNullOrEmpty(path))
                    return;

                //string str = JsonConvert.SerializeObject(flowGraphSurface.OnSerialize());
                //string str = FastJson.Serialize(flowGraphSurface.OnSerialize());
                ISerializeEntity entity = flowGraphSurface.CreateEntity();
                flowGraphSurface.OnSerialize_t(entity);
                string str = FastJson.Serialize(entity);
                Debug.Log("json : " + str);

                //FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
                //StreamWriter sw = new StreamWriter(fs);
                //sw.Write(str);
                //sw.Flush();
                //fs.Flush();
                //sw.Close();
                //fs.Close();

                File.WriteAllText(path, str);
                AssetDatabase.Refresh();
            }
            if (GUILayout.Button("Load", EditorStyles.toolbarButton, GUILayout.Width(60)))
            {
                string path = EditorUtility.OpenFilePanel("Load", resPath, "json");

                if (string.IsNullOrEmpty(path))
                    return;

                string str = File.ReadAllText(path);

                graph.OnDestroy();
                flowGraphSurface.OnDestroy();

                graph = new FlowGraph(new Context(), new Flow());
                flowGraphSurface = new FlowGraphSurface(graph);
                flowGraphSurface.OnDeserialize_t(FastJson.Deserialize<FlowGraphSurface_entity>(str));
            }
            GUILayout.EndHorizontal();
            GUILayout.EndArea();

        }

        private void OnInspectorUpdate()
        {
            if (willRepaint)
            {
                Repaint();
                if (flowGraphSurface != null) { flowGraphSurface.willRepaint = false; }
                if (nodeInfoEditor != null) { nodeInfoEditor.invokeParentRepaint = false; }
                if (contextWin != null) { contextWin.invokeParentRepaint = false; }
            }
        }
    }
}